package com.org.utils.conf;

import java.io.IOException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * configure Base类
 * 
 * @author 
 * @date 2011.12.30
 * @CopyRight(c)2011 Intergrity Ltd.
 */
public abstract class BaseConfigure implements Configure {

	/** 配置文件名称 */
	protected String configureFileName;

	/** 编码 */
	protected String encoding;

	/** 属性缓存 */
	protected static Map<Object, Object> propertyCache = new Hashtable<Object, Object>();

	/** 属性对像缓存 */
	protected static Map<Object, Object> propertyObjectCache = new Hashtable<Object, Object>();
	protected static Log log = LogFactory.getLog(BaseConfigure.class);

	/**
	 * 构造器
	 * 
	 * @param fileName
	 * @throws IOException
	 * @implements by :
	 */
	public BaseConfigure(String fileName) throws IOException {
		this(fileName, "UTF-8");
	}

	/**
	 * 构造器
	 * 
	 * @param fileName
	 * @param encoding
	 * @throws IOException
	 * @implements by :
	 */
	public BaseConfigure(String fileName, String encoding) throws IOException {
		configureFileName = null;
		this.encoding = "UTF-8";
		configureFileName = fileName;
		this.encoding = encoding;
	}

	/**
	 * 获取子对象
	 * 
	 * @return Object
	 * @implements by :
	 */
	public synchronized Object getChildrenObject(String parentPropertyName,
			String className) throws IOException {
		Object obj = null;
		List<String> propertyNames = null;
		Class<?> c = null;
		obj = propertyObjectCache.get(parentPropertyName);
		if (obj != null)
			return obj;
		String names[] = getChildrenPropertyNames(parentPropertyName);
		propertyNames = new ArrayList<String>(10);
		for (int i = 0; i < names.length; i++)
			propertyNames.add(names[i]);
		try {
			c = Class.forName(className);
			obj = c.newInstance();
		} catch (Exception e) {
			log.error(e.getMessage(), e);
			throw new IOException(e.getMessage());
		}
		Method m[] = c.getMethods();
		for (int i = 0; i < m.length; i++) {
			String methodName = m[i].getName();
			if (!methodName.startsWith("set"))
				continue;
			String propertyName = methodName.substring(methodName
					.indexOf("set") + 3);
			propertyName = parentPropertyName + "."
					+ propertyName.substring(0, 1).toLowerCase()
					+ propertyName.substring(1);
			if (!propertyNames.contains(propertyName))
				continue;
			try {
				Object args[] = new String[1];
				args[0] = getProperty(propertyName);
				m[i].invoke(obj, args);
				continue;
			} catch (Exception e) {
				log.error(e.getMessage(), e);
				throw new IOException(e.getMessage());
			}
		}

		propertyObjectCache.put(parentPropertyName, obj);
		return obj;
	}

	/**
	 * 将属性名称以.分解成字符串数组方法
	 * 
	 * @param name
	 * @return String []
	 * @implements by :
	 */
	protected String[] parsePropertyName(String name) {
		List<String> propName = new ArrayList<String>(5);
		for (StringTokenizer tokenizer = new StringTokenizer(name, "."); tokenizer
				.hasMoreTokens(); propName.add(tokenizer.nextToken()))
			;
		return (String[]) propName.toArray(new String[propName.size()]);
	}

	/**
	 * 清除缓存
	 * 
	 * @implements by :
	 * 
	 */
	protected static synchronized void clearCache() {
		propertyCache = new Hashtable<Object, Object>();
		propertyObjectCache = new Hashtable<Object, Object>();
	}

}
